package com.ltmonitor.jt808.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.ltmonitor.dao.IBaseIbatisDao;
import com.ltmonitor.entity.GpsInfo;
import com.ltmonitor.service.IBatchInsertService;
import com.ltmonitor.util.DateUtil;

/**
 * 批量插入数据库服务 先在gps定位数据加入队列，然后开启线程，不断的取出批量插入
 * 
 * @author DELL
 * 
 */
@Service("batchInsertService")
public class BatchInsertService implements IBatchInsertService {
	private ConcurrentLinkedQueue<GpsInfo> dataQueue = new ConcurrentLinkedQueue();

	private static Logger logger = Logger.getLogger(BatchInsertService.class);
	/**
	 * 批量处理实时数据的线程
	 */
	private Thread processRealDataThread;

	@Autowired
	IBaseIbatisDao baseIbatisDao;

	@Value("#{config.batchInsertInterval}")
	private int batchInsertInterval = 10000;

	@Value("#{config.batchInsertNum}")
	private int batchInsertNum = 5000;

	public void start() {
		processRealDataThread = new Thread(new Runnable() {
			public void run() {
				ProcessRealDataThreadFunc();
			}
		});
		processRealDataThread.start();

	}

	public void stopService() {
		try {
			processRealDataThread.join(20000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public int getQueueNum() {
		return this.dataQueue.size();
	}

	public void enQueue(GpsInfo g) {
		this.dataQueue.add(g);
	}

	private void ProcessRealDataThreadFunc() {

		while (baseIbatisDao == null) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
		}

		while (true) {
			int queueNum = 0;
			queueNum = dataQueue.size();
			if (queueNum > 1000) {
				logger.error("历史数据批量插入队列排队:" + queueNum);
			}

			Date today = new Date();
			String strToday = DateUtil.toStringByFormat(today, "yyyyMMdd");
			try {
				GpsInfo tm = dataQueue.poll();
				if (tm != null) {
					final List<GpsInfo> gpsInfoList = new ArrayList<GpsInfo>();
					while (tm != null) {
						String tableName = DateUtil.toStringByFormat(
								tm.getSendTime(), "yyyyMMdd");
						if (tableName.compareTo(strToday) > 0)
							tableName = strToday;// 日期超出当前日期
						tableName = "gpsInfo" + tableName;
						tm.setTableName(tableName);

						gpsInfoList.add(tm);
						if (gpsInfoList.size() > batchInsertNum) {
							break;
						}
						tm = dataQueue.poll();
					}

					if (gpsInfoList.size() > 0) {
						//調用mybatis 的sql文件jt808server.xml中的Id为insertGpsInfo sql片段
						this.baseIbatisDao.batchInsert("jt808server.insertGpsInfo",
								gpsInfoList);
						// batchInsert(gpsInfoList);
						Date end = new Date();
						double seconds = DateUtil.getSeconds(today, end);
						if (seconds > 1)
							logger.error("批量插入耗时:" + seconds + ",插入条数"
									+ gpsInfoList.size());
					}
				}
				// queueNum = dataQueue.size();
			} catch (Exception e) {
				logger.error("批量插入异常:" + e.getMessage(), e);
			}
			try {

				if (queueNum >= this.batchInsertNum) {
					Thread.sleep(50);
				} else
					Thread.sleep(batchInsertInterval);
			} catch (InterruptedException e1) {
				logger.error("批量插入线程错误:" + e1.getMessage(), e1);
			}
		}
	}

	public void batchInsert(List<GpsInfo> gpsInfoList) {
		Date today = new Date();
		String strToday = DateUtil.toStringByFormat(today, "yyyyMMdd");
		try {
			int gpsInfoNum = gpsInfoList.size();
			if (gpsInfoNum > 0) {
				for (GpsInfo g : gpsInfoList) {

				}

				this.baseIbatisDao.batchInsert("insertGpsInfo", gpsInfoList);
			}
			if (gpsInfoNum > 100) {
				Date end = new Date();
				double seconds = DateUtil.getSeconds(today, end);
				logger.error("批量插入耗时:" + seconds + ",条数：" + gpsInfoList.size());
			}

		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}
	}

	public int getBatchInsertInterval() {
		return batchInsertInterval;
	}

	public void setBatchInsertInterval(int batchInsertInterval) {
		this.batchInsertInterval = batchInsertInterval;
	}

	public int getBatchInsertNum() {
		return batchInsertNum;
	}

	public void setBatchInsertNum(int batchInsertNum) {
		this.batchInsertNum = batchInsertNum;
	}

	@Override
	public void enQueue(List<GpsInfo> gpsInfoList) {
		// TODO Auto-generated method stub

	}

}
